home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / NextAnswers / 1196_integrating_C++_code.rtf < prev    next >
Text File  |  1995-06-12  |  6KB  |  137 lines

  1. {\rtf0\ansi{\fonttbl\f0\fnil Times-Roman;\f2\fmodern Courier;\f1\fmodern Ohlfs;}
  2. \paperw11760
  3. \paperh7200
  4. \margl120
  5. \margr120
  6. {\colortbl;\red0\green0\blue0;\red84\green84\blue84;\red83\green83\blue83;}
  7. \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\f0\b0\i0\ulnone\fs28\fc1\cf1 Q:  Can I integrate C++ code into my InterfaceBuilder/Objective-C application?  How?\
  8. \
  9. A:  Yes, in Release 2 and following releases you can, and it's pretty easy (once you know how)!  The procedure breaks down into three categories of things that you must do: compiling, ProjectBuilder and getting the two languages to talk to each other.\
  10. \
  11.  
  12. \b Compiling
  13. \b0 \
  14. First, you must use the C++ compiler for 
  15. \i all
  16. \i0  of your source files—including the Objective-C sources.  To do this, add the following line to your Makefile.preamble:\
  17.  
  18. \f2     \
  19.  
  20. \pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\fs24\fc1\cf1     CC=cc++\
  21.  
  22. \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\f0\fs28\fc1\cf1 \
  23. Now that you are using the C++ compiler, you have to notify the compiler when/if your header files contain non-C++ code.  For Objective-C header files, encapsulate your 
  24. \f2\fs24 #import
  25. \f0\fs28  directives like this:\
  26. \
  27.  
  28. \pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\f2\fs24\fc1\cf1     extern "Objective-C"        \
  29.     \{                \
  30.     #import <appkit/Application.h>\
  31.     #import <appkit/Panel.h>\
  32.     #import <appkit/TextField.h>\
  33.     #import <appkit/Button.h>\
  34.     \}\
  35.  
  36. \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\f0\fs28\fc1\cf1 \
  37. For regular C header files, encapsulate your 
  38. \f2\fs24 #import
  39. \f0\fs28  directives like this: \
  40. \
  41.  
  42. \pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\f2\fs24\fc1\cf1     extern "C"\
  43.     \{\
  44.     #import <appkit/publicWraps.h>\
  45.     #import <objc/error.h>\
  46.     #import <objc/NXStringTable.h>\
  47.     #import <strings.h>\
  48.     \}\
  49.  
  50. \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\fs28\fc1\cf1     \
  51.  
  52. \pard\tx620\tx1240\tx1860\tx2480\tx3100\tx3720\tx4340\tx4980\tx5600\tx6220\f0\fc1\cf1 The C++ "linkage" directive serves two purposes (when importing interface files that contain straight ANSI-C/Objective-C code). It:\
  53. \
  54.  
  55. \pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\fi-980\li980\fc0\cf0 •    a
  56. \fc1\cf1 llows you to link with libraries that have not been compiled with the C++ compiler. Since libraries in NEXTSTEP are compiled  with the Objective-C compiler (cc, not cc++), you must use the C++ linkage directive when importing interface files that represent NeXT  libraries (or any library that is not compiled with cc++). \
  57. \
  58.  
  59. \fc0\cf0 •    
  60. \fc1\cf1 tells the compiler to ignore C++ keywords that result in syntax errors when importing ANSI-C or Objective-C interface files.  The linkage directive essentially tells the C++ compiler to treat keywords (such as the method names "new", "delete", etc.) as normal identifiers.\
  61.  
  62. \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\fc1\cf1 \
  63.  
  64. \b ProjectBuilder\
  65.  
  66. \b0 Within InterfaceBuilder you need to add the C++ 
  67. \b .c
  68. \b0  and 
  69. \b .h
  70. \b0  files to your project.  Add the files separately—the 
  71. \b .c
  72. \b0  file goes in the Other Sources directory, and the 
  73. \b .h
  74. \b0  file goes in the Headers directory. \
  75. \
  76. If you already have a 
  77. \b _main.m
  78. \b0  file, make sure that the option in ProjectBuilder for generating the main file is turned 
  79. \i off
  80. \i0 .  Then, remove the void declaration of the main procedure by replacing:\
  81. \
  82.  
  83. \pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\f2\fs24\fi-980\li980\fc1\cf1     void main(int argc, char *argv[]) \{\
  84.  
  85. \pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\fs28\fc1\cf1     
  86. \fs24 \
  87.  
  88. \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\f0\fs28\fc1\cf1 with:\
  89. \
  90.  
  91. \pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\f2\fs24\fi-980\li980\fc1\cf1      main(int argc, char *argv[]) \{\
  92.  
  93. \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\f0\fs28\fc1\cf1 \
  94.  
  95. \b Modifying Source Code
  96. \b0 \
  97. Since the nib files generated by InterfaceBuilder are based the AppKit, and it generates source templates in Objective-C, we must envision our program such that Objective-C and nib files are the foundation of our program, and the C++ code is a supporting library.\
  98. \
  99. Now that we can compile, we need to get an Objective-C object and a C++ object to pass messages to one another.  Suppose that we have two created objects—a C++ object and an Objective-C object.  This is how you
  100. \b  
  101. \b0 would refer to the C++ object and tell it to "do something":\
  102.     
  103. \pard\tx620\tx1240\tx1860\tx2480\tx3100\tx3720\tx4340\tx4980\tx5600\tx6220\fc1\cf1     
  104. \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\fc1\cf1 \
  105.  
  106. \pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\f2\fs24\fi-980\li980\fc1\cf1     class CalcEngine     *cplus_object;    \
  107.     cplus_object = new CalcEngine;\
  108.     cplus_object->doSomething();\
  109.  
  110. \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\f0\fs28\fc1\cf1         \
  111.  C++ objects are implemented as regular C structures, so to access public instance variables, or public methods of a C++ object, you dereference the object with the -> syntax as you would a structure member. And this is how you would refer to an Objective-C object from C++:\
  112.         \
  113.  
  114. \pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\f2\fs24\fi-980\li980\fc1\cf1     id objectiveObj;\
  115.         \
  116.     objectiveObj = [ObjectiveObjCls new];\
  117.     [objectiveObj doSomethingElse:what];\
  118.  
  119. \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\f0\fs28\fc1\cf1 \
  120. Basically, in either case you use the language constructs of the object to which you are referring, and embed them in the source file of the other language.\
  121.     \
  122.  
  123. \b Example
  124. \b0 \
  125. There is an example located in /NextDeveloper/Examples/AppKit/CalculatorLab++ which illustrates the integration of InterfaceBuilder nib files, Objective-C source code, and C++ source code into one program.\
  126. \
  127. QA584\
  128. \
  129.  
  130. \pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\fc0\cf0 Valid for 2.0, 
  131. \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\fc1\cf1 3.0\
  132. See also ../NEXTSTEP_Developer/Objective_C/
  133. \fc0\cf0 NeXT_position_on_C++
  134. \fc1\cf1 .\
  135. \
  136.  
  137.